﻿using ConsoleApp.Model.Dto;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp.Service
{
    public class HttpService :IHttpService
    {


        public async Task<LoginRes> DoLogin(LoginModel param)
        {
            string loginUrl = "https://api.moguding.net:9000/session/user/v3/login";
            HttpHeader header = new HttpHeader();
            string resStr = await HttpHelper<LoginModel>.DoPost(loginUrl, header, param);
            LoginRes res = JsonConvert.DeserializeObject<LoginRes>(resStr);
            return res;
        }

        public async Task<PlanRes> getPlanByStu(string userid, string roleKey, string token)
        {
            string sign = HelpFunc.getPlanByStuSign(userid, roleKey);
            string url = "https://api.moguding.net:9000/practice/plan/v3/getPlanByStu";
            HttpHeader header = new HttpHeader();
            header.Sign = sign;
            header.RoleKey = roleKey;
            header.Authorization = token;
            string resStr = await HttpHelper<object>.DoPost(url, header, new { state = "" });
            PlanRes res = JsonConvert.DeserializeObject<PlanRes>(resStr);
            return res;
        }

        public async Task<InfoDto> GetOrSaveTokenInfo(LoginModel loginParam)
        {
            InfoDto dto = new InfoDto();
            var configBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
            var configSection = configBuilder.GetSection("redis");
            var host = configSection["host"] ?? null;
            var password = configSection["password"] ?? null;
            long port = long.Parse(configSection["port"].ToString());
            ConnectionMultiplexer redis = await ConnectionMultiplexer.ConnectAsync($"{host}:{port},password={password}");
            var db = redis.GetDatabase(0);
            string? token = db.StringGet("auto_ding_token");
            string userId = "";
            string roleKey = "";
            if (!string.IsNullOrEmpty(token))
            {
                userId = db.StringGet("auto_ding_userId");
                roleKey = db.StringGet("auto_ding_roleKey");
                string planId = db.StringGet("auto_ding_planId");
                dto.token = token;
                dto.userId = userId;
                dto.roleKey = roleKey;
                dto.planId = planId;
            }
            else
            {
                LoginRes loginRes = await DoLogin(loginParam);
                int code = loginRes.code;
                if (code == 200)
                {
                    Dictionary<string, object> data = loginRes.data;
                    token = data.GetValueOrDefault("token") as string;
                    userId = data.GetValueOrDefault("userId") as string;
                    JArray roleGroup = data.GetValueOrDefault("roleGroup") as JArray;
                    JToken role = roleGroup[0];
                    roleKey = HelpFunc.JSON_SeleteNode(role, "roleKey");
                }
                else
                {
                    Console.WriteLine("code:" + loginRes.code + ",msg:" + loginRes.msg);
                }
            }

            PlanRes plan = await getPlanByStu(userId, roleKey, token);

            Console.WriteLine("plan - code:" + plan.code + ",msg:" + plan.msg);
            if (plan.code == 200)
            {
                Dictionary<string, object>[] planDics = plan.data;
                Dictionary<string, object> planDic = planDics[0];
                string planId = planDic.GetValueOrDefault("planId") as string;
                TimeSpan timeSpan = new TimeSpan(7, 0, 0, 0);
                db.StringSet("auto_ding_token", token, timeSpan);
                db.StringSet("auto_ding_userId", userId);
                db.StringSet("auto_ding_roleKey", roleKey);
                db.StringSet("auto_ding_planId", planId);
                dto.token = token;
                dto.userId = userId;
                dto.roleKey = roleKey;
                dto.planId = planId;
            }
            else
            {
                if (plan.code == 401)
                {
                    await db.KeyDeleteAsync("auto_ding_token");
                    dto = await GetOrSaveTokenInfo(loginParam);
                }
            }
            return dto;
        }


        public async Task<SignRes> tosign(string description, string address, string province, string city, string longitude, string latitude, string t, string token, string planId, string userId)
        {

            string to_sign = HelpFunc.get_tosign(planId, userId, address);
            string type = "START";

            HttpHeader header = new HttpHeader();
            header.Host = "api.moguding.net:9000";
            header.Sign = to_sign;
            header.Authorization = token;

            Dictionary<string, string> data = new Dictionary<string, string>();
            data.Add("device", "Android");
            data.Add("address", address);
            data.Add("t", t);
            data.Add("description", description);
            data.Add("country", "中国");
            data.Add("area", "鱼峰区");
            data.Add("longitude", longitude);
            data.Add("latitude", latitude);
            data.Add("city", city);
            data.Add("province", province);
            data.Add("planId", planId);
            data.Add("type", type);

            string url = "https://api.moguding.net:9000/attendence/clock/v2/save";
            string resStr = await HttpHelper<Dictionary<string, string>>.DoPost(url, header, data);

            SignRes res = JsonConvert.DeserializeObject<SignRes>(resStr);
            return res;

        }



    }
}
